package cn.calm.user.service.impl;

import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;

import cn.calm.commons.dao.QueryConditionBuilder;
import cn.calm.commons.entity.BaseEntity;
import cn.calm.commons.exception.DeskException;
import cn.calm.commons.service.IBaseService;
import cn.calm.commons.service.defaultimpl.DefaultServiceImpl;
import cn.calm.entity.Application;
import cn.calm.entity.Menu;
import cn.calm.entity.User;
import cn.calm.entity.UserMenuApplication;
import cn.calm.user.action.UserAction;
import cn.calm.user.service.IMenuService;
import cn.calm.user.service.IUserMenuApplicationService;
import cn.calm.user.service.IUserService;

public class UserMenuApplicationServiceImpl<T extends UserMenuApplication>
		extends DefaultServiceImpl<T> implements IUserMenuApplicationService<T> {
	private static final Logger logger = Logger
			.getLogger(UserMenuApplicationServiceImpl.class);
	private IMenuService<Menu> menuService;
	private IUserService<User> userService;
	private IBaseService<Application> applicationService;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.user.service.IUserMenuApplicationService#listByUserIdAndParent
	 * (java.lang.String, cn.desk.user.entity.UserMenuApplication)
	 */
	@Override
	public List<T> listByUserIdAndParent(final String userId,
			final UserMenuApplication parent) {
		try {
			logger.debug("listByUserIdAndParentId start");
			// QueryCondition condition = new QueryCondition();
			// condition.andEq("userId", userId);
			// if (parent == null || parent.getMenuId() == null) {
			// condition.andIsNull("parentId");
			// } else {
			// condition.andEq("parentId", parent.getMenuId());
			// }
			return baseDao.list(UserMenuApplication.class,
					new QueryConditionBuilder<T>() {

						@Override
						public void query(CriteriaBuilder r,
								CriteriaQuery<?> query,Root<? extends BaseEntity> root)  {
//							Root<UserMenuApplication> root = query
//									.from(UserMenuApplication.class);
							/**
							 * userId是当前用户
							 */
							Predicate preUserId = r.equal(root.get("userId"),
									userId);
							Predicate preParent;
							if (parent == null
									|| parent.getId().getMenuId() == null) {
								preParent = r.isNull(root.get("parentId"));
								// condition.andIsNull("parentId");
							} else {
								preParent = r.equal(root.get("parentId"), parent
										.getId().getMenuId());
							}
							query.where(preUserId, preParent);
						}
					});
		} finally {
			logger.debug("listByUserIdAndParentId end");
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.user.service.IUserMenuApplicationService#listAllMenuByUserId(
	 * java.lang.String)
	 */
	@Override
	public List<T> listAllMenuByUserId(final String id) {
		try {
			logger.debug("listAllMenuByUserId start");
			// QueryCondition condition = new QueryCondition();
			// condition.andEq("userId", id);
			// condition.andIsNull("applicationId");
			return baseDao.list(UserMenuApplication.class, new QueryConditionBuilder<T>() {

				@Override
				public void query(CriteriaBuilder cb, CriteriaQuery<?> arg1,Root<? extends BaseEntity> root)  {
//					Root<UserMenuApplication> root=	arg1.from(UserMenuApplication.class);
					Predicate userId= cb.equal(root.get("userId"),id);
					Predicate applicationId= cb.isNull(root.get("applicationId"));
					arg1.where(userId,applicationId);
				}
			});
		} finally {
			logger.debug("listAllMenuByUserId end");
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.impl.BaseServiceImpl#add(cn.desk.commons.entity
	 * .BaseEntity)
	 */
	public void add(T t) {
		logger.debug("add start");
		Menu menu = new Menu();
		menu.setName(t.getMenuName());
		menu.setIcon(t.getIcon());
		User u = (User) ServletActionContext.getRequest().getSession()
				.getAttribute(UserAction.SESSION_KEY_USER);
		User temp = userService.load(u);
		menu.getUsers().add(temp);
		if (t.getParentId() != null && !"".equals(t.getParentId())) {
			Menu parent = new Menu();
			parent.setId(t.getParentId());
			parent = menuService.load(parent);
			menu.setParent(parent);
		}
		if (t.getApplicationId() != null && !"".equals(t.getApplicationId())) {
			Application application = new Application();
			application.setId(t.getApplicationId());
			application = applicationService.load(application);
			menu.setApplication(application);
		}
//		String id = String.valueOf(getNextId(Menu.class));
//		menu.setId(id);
		menuService.add(menu);
		logger.debug("add end");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.impl.BaseServiceImpl#update(cn.desk.commons.entity
	 * .BaseEntity)
	 */
	public void update(T t) throws DeskException {
		logger.debug("update start");
		Menu menu = new Menu();
		menu.setId(t.getId().getMenuId());
		menu = menuService.load(menu);
		menu.setName(t.getMenuName());
		menu.setIcon(t.getIcon());
		if (t.getParentId() == null || "".equals(t.getParentId())) {
			menu.setParent(null);
		} else {
			Menu parent = new Menu();
			parent.setId(t.getParentId());
			parent = menuService.load(parent);
			menu.setParent(parent);
		}
		if (t.getApplicationId() == null || "".equals(t.getApplicationId())) {
			menu.setApplication(null);
		} else {
			Application application = new Application();
			application.setId(t.getApplicationId());
			application = applicationService.load(application);
			menu.setApplication(application);
		}
		menuService.update(menu);
		logger.debug("update end");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.impl.BaseServiceImpl#delete(cn.desk.commons.entity
	 * .BaseEntity)
	 */
	public void delete(T t) {
		logger.debug("delete start");
		Menu menu = new Menu();
		menu.setId(t.getId().getMenuId());
		menu = menuService.load(menu);
		List<Menu> submenu = menuService.listByProperty(Menu.class, "parent",
				menu);
		if (submenu.size() > 0) {
			throw new DeskException("EMDT0002", menu);
		}
		User u = (User) ServletActionContext.getRequest().getSession()
				.getAttribute(UserAction.SESSION_KEY_USER);
		User temp = userService.load(u);
		temp.getMenu().remove(menu);
		userService.update(temp);
		menuService.delete(menu);
		logger.debug("delete end");

	}

	public void setMenuService(IMenuService<Menu> menuService) {
		this.menuService = menuService;
	}

	public void setUserService(IUserService<User> userService) {
		this.userService = userService;
	}

	public void setApplicationService(
			IBaseService<Application> applicationService) {
		this.applicationService = applicationService;
	}
}
